<template>
  <Form
    ref="formRef"
    v-bind="$attrs"
    :class="getFormClass"
    @keydown.enter="handleEnterPress"
    layout="inline"
  >
    <!-- 标签 -->
    <FormItem :label="`${t('common.searchText')}：`">
      <div></div>
    </FormItem>
    <!-- 属性选择框 -->
    <FormItem style="min-width: 150px">
      <Select
        v-model:value="filterRule.Field"
        show-search
        :filterOption="handleFilterOption"
        :placeholder="t('component.adtable.search.selectColumn')"
        @change="handleChange(filterRule)"
      >
        <SelectOption
          v-for="item in columns"
          :key="item.field"
          :value="item.field"
          :label="item.title"
        >
          {{ item.title }}
        </SelectOption>
      </Select>
    </FormItem>
    <!-- 条件选择框 -->
    <FormItem style="min-width: 110px">
      <Select
        v-model:value="filterRule.Operate"
        show-search
        :filterOption="handleFilterOption"
        :placeholder="t('component.adtable.search.selectOperate')"
      >
        <SelectOption
          v-for="entity in filterRule.column?.entities"
          :key="entity.Operate"
          :value="entity.Operate"
          :label="entity.Display"
        >
          {{ entity.Display }}
        </SelectOption>
      </Select>
    </FormItem>
    <!-- 搜索值输入框 -->
    <FormItem style="min-width: 185px">
      <Tooltip :trigger="['hover']" placement="top">
        <template v-if="filterRule.Value" #title>
          <span>
            {{ filterRule.Value }}
          </span>
        </template>
        <!-- 固定枚举 -->
        <Select
          v-if="filterRule.column?.formRender?.name === 'Select'"
          v-model:value="filterRule.Value"
          :dropdownMatchSelectWidth="false"
          show-search
          :filterOption="handleFilterOption"
          :placeholder="t('component.adtable.search.selectValue')"
        >
          <SelectOption
            v-for="item in filterRule.column?.enumData"
            :key="item.value"
            :value="item.value"
            :label="item.label"
          >
            {{ item.label }}
          </SelectOption>
        </Select>
        <!-- 远程下拉 -->
        <ApiSelect
          v-if="filterRule.column?.formRender?.name === 'ApiSelect'"
          v-model:value="filterRule.Value"
          :dropdownMatchSelectWidth="false"
          :placeholder="t('component.adtable.search.selectValue')"
          :api="filterRule.column?.formRender?.props?.api"
          :params="filterRule.column?.formRender?.props?.params"
          :immediate="filterRule.column?.formRender?.props?.immediate"
          :resultField="filterRule.column?.formRender?.props?.resultField"
          :labelField="filterRule.column?.formRender?.props?.labelField"
          :valueField="filterRule.column?.formRender?.props?.valueField"
          :allowClear="filterRule.column?.formRender?.props?.allowClear"
          :showSearch="filterRule.column?.formRender?.props?.showSearch"
          :optionFilterProp="filterRule.column?.formRender?.props?.optionFilterProp"
        />
        <!-- 远程下拉树 -->
        <ApiTreeSelect
          v-if="filterRule.column?.formRender?.name === 'ApiTreeSelect'"
          v-model:value="filterRule.Value"
          :dropdownMatchSelectWidth="false"
          :placeholder="t('component.adtable.search.selectValue')"
          :api="filterRule.column?.formRender?.props?.api"
          :params="filterRule.column?.formRender?.props?.params"
          :immediate="filterRule.column?.formRender?.props?.immediate"
          :resultField="filterRule.column?.formRender?.props?.resultField"
          :labelField="filterRule.column?.formRender?.props?.labelField"
          :valueField="filterRule.column?.formRender?.props?.valueField"
          :childrenField="filterRule.column?.formRender?.props?.childrenField"
          :allowClear="filterRule.column?.formRender?.props?.allowClear"
          :showSearch="filterRule.column?.formRender?.props?.showSearch"
          :treeNodeFilterProp="filterRule.column?.formRender?.props?.treeNodeFilterProp"
          :treeDefaultExpandAll="filterRule.column?.formRender?.props?.treeDefaultExpandAll"
        />
        <!-- 数值类型 -->
        <InputNumber
          v-if="['InputNumber'].includes(filterRule.column?.formRender?.name)"
          style="min-width: 185px"
          v-model:value="filterRule.Value"
          :precision="filterRule.column?.formRender?.props?.precision"
          :placeholder="t('component.adtable.search.inputNumber')"
        />
        <!-- 整数/字符类型 -->
        <Input
          v-if="[undefined, null, 'Input'].includes(filterRule.column?.formRender?.name)"
          v-model:value="filterRule.Value"
          :placeholder="
            filterRule.column?.dataType === 'integer'
              ? t('component.adtable.search.inputInteger')
              : t('component.adtable.search.inputString')
          "
          :onkeyup="
            filterRule.column?.dataType === 'integer'
              ? 'value=value.replace(/[^{1,2,3,4,5,6,7,8,9,0}]/g,\'\')'
              : 'value=value'
          "
        />
        <!-- 密码字符类型 -->
        <InputPassword
          v-if="['InputPassword'].includes(filterRule.column?.formRender?.name)"
          v-model:value="filterRule.Value"
          :placeholder="t('component.adtable.search.inputString')"
        />
        <!-- 布尔类型 -->
        <Switch
          v-if="filterRule.column?.formRender?.name === 'Switch'"
          v-model:checked="filterRule.Value"
        />
        <!-- 日期时间/日期 -->
        <DatePicker
          v-if="['DatePicker'].includes(filterRule.column?.formRender?.name)"
          style="width: 185px"
          v-model:value="filterRule.Value"
          :showTime="filterRule.column?.formRender?.props?.showTime"
          :placeholder="
            filterRule.column?.formRender?.props?.showTime
              ? t('component.adtable.search.selectDateTime')
              : t('component.adtable.search.selectDate')
          "
        />
        <!-- 时间 -->
        <TimePicker
          v-if="filterRule.column?.formRender?.name === 'TimePicker'"
          v-model:value="filterRule.Value"
          :placeholder="t('component.adtable.search.selectTime')"
        />
      </Tooltip>
    </FormItem>
    <!-- 按钮组 -->
    <FormItem>
      <DropdownButton type="primary" @click="handleSearchClick">
        <Icon icon="ant-design:search-outlined" />{{ t('common.searchText') }}
        <template #overlay>
          <Menu>
            <MenuItem key="adSearch" @click="handleAdSearchClick">
              <Icon icon="fluent-globe-search-24-regular" />{{ t('common.adSearchText') }}
            </MenuItem>
            <MenuItem key="reset" @click="handleReset">
              <Icon icon="grommet-icons:power-reset" />{{ t('common.resetText') }}
            </MenuItem>
          </Menu>
        </template>
      </DropdownButton>
    </FormItem>
  </Form>

  <SearchModal
    @register="registerSearchModal"
    :resetFn="handleReset"
    :closeFn="handleSearchModalClose"
    :searchFn="handleSearchModalOk"
    :filterGroup="searchInfo"
    :columns="columns"
  />
</template>
<script lang="ts" setup>
  import type { PropType } from 'vue';
  import { ref, computed, unref, onMounted } from 'vue';
  import {
    Form,
    Select,
    InputNumber,
    Input,
    Switch,
    DatePicker,
    TimePicker,
    Menu,
    Dropdown,
    Tooltip,
  } from 'ant-design-vue';
  import { ApiSelect, ApiTreeSelect } from '@/components/Form';
  import Icon from '@/components/Icon/Icon.vue';

  import { useDesign } from '@/hooks/web/useDesign';
  import { useI18n } from '@/hooks/web/useI18n';
  import { useMessage } from '@/hooks/web/useMessage';

  import { propTypes } from '@/utils/propTypes';
  import { changeFilterRuleType } from '../hooks';
  import { AdColumn } from '../types/table';
  import { SearchFormActionType } from '../types/searchForm';

  import { basicProps } from '@/components/Form/src/props';
  // import type { FormProps } from '@/components/Form';
  import { FilterRule, FilterGroup } from '#/request';
  import { FilterOperateEnum } from '@/enums/filterOperateEnum';

  import { useModal } from '@/components/AdVxeModal';
  import SearchModal from './SearchModal.vue';

  // type MenuEvent = 'adSearch' | 'reset';

  const FormItem = Form.Item;
  const SelectOption = Select.Option;
  const InputPassword = Input.Password;
  const MenuItem = Menu.Item;
  const DropdownButton = Dropdown.Button;

  defineOptions({ name: 'SearchForm' });

  const props = defineProps({
    ...basicProps,
    /** 在INPUT组件上单击回车时，是否自动搜索 */
    autoSubmitOnEnter: propTypes.bool.def(true),
    /** 是否在重置时重新发起搜索 */
    submitOnReset: propTypes.bool.def(true),
    /** 加载中 */
    loading: propTypes.bool.def(false),
    /** 列配置 */
    columns: {
      type: [Array] as PropType<AdColumn[]>,
      default: () => [],
    },
  });
  const emit = defineEmits(['search-click', 'reset-click', 'register']);

  const { t } = useI18n();
  const { createMessage } = useMessage();
  const formRef = ref();
  // const propsRef = ref<Partial<FormProps>>({});
  const { prefixCls } = useDesign('search-form');

  const getProps = computed(() => {
    // return { ...props, ...unref(propsRef) };
    return props;
  });

  const getFormClass = computed(() => {
    return [
      prefixCls,
      {
        [`${prefixCls}--compact`]: unref(getProps).compact,
      },
    ];
  });

  const searchInfo = ref<FilterGroup>(new FilterGroup());
  const filterRule = ref<FilterRule>(new FilterRule(undefined, null));

  const [registerSearchModal, { openModal: openSearchModal }] = useModal();

  /** 处理选择 */
  function handleChange(rule: FilterRule) {
    if (!rule) {
      return;
    }
    rule.column = props.columns.find((n) => n.field === rule.Field) as AdColumn;
    if (!rule.column) {
      return;
    }
    changeFilterRuleType(rule, rule.column);
  }
  /** 处理选择框筛选 */
  const handleFilterOption = (input: string, option: any) => {
    return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
  };

  /** 处理回车事件 */
  function handleEnterPress(e: KeyboardEvent) {
    const { autoSubmitOnEnter } = props;
    if (!autoSubmitOnEnter) return;
    if (
      e.key.toLowerCase() === 'Enter'.toLowerCase() &&
      e.target &&
      e.target instanceof HTMLElement
    ) {
      handleSearchClick();
      // const target: HTMLElement = e.target as HTMLElement;
      // if (target && target.tagName && target.tagName.toUpperCase() == 'INPUT') {
      //   handleSearchClick();
      // }
    }
  }

  /** 处理搜索点击 */
  function handleSearchClick() {
    if (
      filterRule.value.Field === undefined ||
      filterRule.value.Field === null ||
      filterRule.value.Field === ''
    ) {
      createMessage.error(t('component.adtable.search.selectColumnPlaceholder'));
      return;
    }
    if (filterRule.value.Operate === undefined || filterRule.value.Operate === null) {
      createMessage.error(t('component.adtable.search.selectOperatePlaceholder'));
      return;
    }

    // 重置搜索条件为简单条件
    searchInfo.value.Rules = [];
    searchInfo.value.Groups = [];
    searchInfo.value.Operate = FilterOperateEnum.And;
    searchInfo.value.Rules = [filterRule.value];

    handleSearch();
  }
  /** 处理高级搜索按钮点击 */
  function handleAdSearchClick() {
    if (
      props.columns.length === undefined ||
      props.columns.length === null ||
      props.columns.length <= 0
    ) {
      createMessage.error(t('component.adtable.search.adSearchEmpty'));
      return;
    }
    //TODO:搜索的弹窗
    openSearchModal(true);
  }

  /** 处理搜索关闭按钮 */
  async function handleSearchModalClose() {
    return true;
    // try {
    //   return true;
    // } catch (error) {
    //   if ((error as unknown as Error)?.message) {
    //     createMessage.error((error as unknown as Error)?.message);
    //   }
    //   return false;
    // }
  }
  /** 处理搜索确认按钮 */
  async function handleSearchModalOk() {
    try {
      const verified = verificationFilterGroup(getSearchInfo());
      if (verified === true) {
        handleSearch();
      }
      return verified;
    } catch (error) {
      if ((error as unknown as Error)?.message) {
        createMessage.error((error as unknown as Error)?.message);
      }
      return false;
    }
  }

  /** 处理搜索点击 */
  function handleSearch() {
    emit('search-click', getSearchInfo());
  }
  /** 处理重置 */
  async function handleReset() {
    clearFormData();

    emit('reset-click');

    const { submitOnReset } = props;
    submitOnReset && emit('search-click', getSearchInfo());
  }
  /** 清除窗体数据 */
  function clearFormData() {
    filterRule.value.column = undefined;

    filterRule.value.Field = undefined;
    filterRule.value.Operate = undefined;
    filterRule.value.Value = null;
    filterRule.value.Control = 'string';
    filterRule.value.Entries = [];

    searchInfo.value.Rules = [];
    searchInfo.value.Groups = [];
    searchInfo.value.Operate = FilterOperateEnum.And;
  }
  /** 获取搜索信息 */
  function getSearchInfo(): FilterGroup {
    return searchInfo.value;
  }

  /** 验证查询条件组 */
  function verificationFilterGroup(filterGroup: FilterGroup): boolean {
    if (filterGroup !== undefined && filterGroup !== null) {
      if (filterGroup.Rules?.length > 0) {
        for (let rule of filterGroup.Rules) {
          // console.log(rule);
          if (rule.Field === undefined || rule.Field === null || rule.Field === '') {
            createMessage.error(t('component.adtable.search.selectColumnPlaceholder'));
            return false;
          }
          if (rule.Operate === undefined || rule.Operate === null) {
            createMessage.error(t('component.adtable.search.selectOperatePlaceholder'));
            return false;
          }
        }
      }
      if (filterGroup.Groups?.length > 0) {
        for (let group of filterGroup.Groups) {
          const verified = verificationFilterGroup(group);
          if (verified === false) {
            return verified;
          }
        }
        // filterGroup.Groups.map((group) => verificationFilterGroup(group));
      }
    }
    return true;
  }

  const formActionType: Partial<SearchFormActionType> = {
    getSearchInfo: getSearchInfo,
  };

  onMounted(() => {
    emit('register', formActionType);
  });
</script>

<style lang="less">
  @prefix-cls: ~'@{namespace}-search-form';

  .@{prefix-cls} {
    .ant-input-number {
      width: 100%;
      max-width: 100%;
    }

    .ant-form-item {
      &-label label::after {
        margin: 0 6px 0 2px;
      }

      &-with-help {
        margin-bottom: 0;
      }

      &:not(.ant-form-item-with-help) {
        margin-bottom: 20px;
      }

      &.suffix-item {
        .ant-form-item-children {
          display: flex;
        }

        .ant-form-item-control {
          margin-top: 4px;
        }

        .suffix {
          display: inline-flex;
          align-items: center;
          margin-top: 1px;
          padding-left: 6px;
          line-height: 1;
        }
      }
    }

    .ant-form-explain {
      font-size: 14px;
    }

    &--compact {
      .ant-form-item {
        margin-bottom: 8px !important;
      }
    }
  }
</style>
